package compute;

import java.util.ArrayList;

import data.DataBloc;
import data.Key;

public class DesCtr extends Mode {

	byte[] nonce;

	public DesCtr(byte[] nonce) {
		blocEncrypter = new DES();
		this.nonce = nonce;
	}

	public DesCtr(Key k, byte[] nonce) {
		blocEncrypter = new DES(k);
		this.nonce = nonce;
	}

	@Override
	public byte[] encrypt(String plainText) {
		DataBloc IV = DataBloc.toDataBlocs(nonce).get(0);

		ArrayList<DataBloc> plainTextData = DataBloc.toDataBloc(plainText);

		ArrayList<DataBloc> cypherTextData = new ArrayList<DataBloc>();

		for (DataBloc Mi : plainTextData) {
			IV = blocEncrypter.encrypt(IV);
			byte[] IVBytes = IV.getBytes();
			byte[] MiBytes = Mi.getBytes();
			byte[] xorResult = new byte[MiBytes.length];
			for (int i = 0; i < MiBytes.length; i++) {
				xorResult[i] = (byte) (IVBytes[i] ^ MiBytes[i]);
			}
			cypherTextData.add(DataBloc.toDataBlocs(xorResult).get(0));
		}
		return DataBloc.toBytes(cypherTextData);
	}

	@Override
	public String decrypt(byte[] cypherText) {

		DataBloc IV = DataBloc.toDataBlocs(nonce).get(0);

		ArrayList<DataBloc> cypherTextData = DataBloc.toDataBlocs(cypherText);

		ArrayList<DataBloc> plainTextData = new ArrayList<DataBloc>();
		for (DataBloc Ci : cypherTextData) {
			IV = blocEncrypter.encrypt(IV);
			byte[] IVBytes = IV.getBytes();
			byte[] CiBytes = Ci.getBytes();
			byte[] xorResult = new byte[CiBytes.length];
			for (int i = 0; i < CiBytes.length; i++) {
				xorResult[i] = (byte) (IVBytes[i] ^ CiBytes[i]);
			}
			plainTextData.add(DataBloc.toDataBlocs(xorResult).get(0));
		}
		return DataBloc.toString(plainTextData);
	}

	public Key getKey() {
		return ((DES) blocEncrypter).getKey();
	}

	public void setKey(Key k) {
		((DES) blocEncrypter).setKey(k);
	}

	public static void main(String[] args) {
		DesEcb desecb = new DesEcb();
		String originalText = "Il était une fois dans l'ouest.";
		byte[] cypherText = desecb.encrypt(originalText);
		String plainText = desecb.decrypt(cypherText);
		System.out.println(originalText);
		System.out.println(cypherText.toString());
		System.out.println(plainText);
	}
}
